<template>
<div
	:class="[
		'bh-input-number',
		inputNumberSize ? 'bh-input-number--' + inputNumberSize : '',
		{ 
			'is-disabled': inputNumberDisabled,
			'is-controls-right': controlsAtRight
		}
	]">
	<span class="bh-input-number__decrease" @click='decrease'>
		<i :class="`bh-icon-${controlsAtRight ? 'arrow-down' : 'minus'}`"></i>
	</span>
	<span class="bh-input-number__increase" @click='increase'>
		<i :class="`bh-icon-${controlsAtRight ? 'arrow-up' : 'plus'}`"></i>
	</span>
	<bh-input 
		:value='displayValue' 
		:placeholder='placeholder' 
		:disabled='inputNumberDisabled' 
		:size="inputNumberSize"
		@blur="handleBlur"
		@focus="handleFocus"
		@input='handleInput' 
		@change="handleInputChange"></bh-input>
</div>
</template>

<script>
export default {
	name: 'bh-input-number',
	props: {
		name: String,
		value: {},
		disabled: Boolean,
		label: String,
		placeholder: String,
		max: {
			type: Number,
			default: Infinity
		},
		min: {
			type: Number,
			default: -Infinity
		},
		step: {
			type: Number,
			default: 1,
		},
		size: String,
		stepStrictly: {
			type: Boolean,
			default: false
		},
		controlsPosition: {
			type: String,
			default: ''
		},
		precision: {
			type: Number,
			validator(val) {
				return val >= 0 && val === parseInt(val, 10);
			}
		},
	},
	data() {
		return {
			currentValue: 0,
			userInput: null,//用于输入时值
		};
    },
    watch: {
		value: {
			immediate: true,
			handler(value) {
				let newVal = value === undefined ? value : Number(value);
				if (newVal !== undefined) {
					if (newVal >= this.max) newVal = this.max;
					if (newVal <= this.min) newVal = this.min;
					this.currentValue = newVal;
					this.userInput = null;
					this.$emit('input', newVal);
				}
			}
		}
    },
	computed: {
		displayValue() {
			console.log('displayValue');
			if (this.userInput !== null) {
				return this.userInput;
			}
			let currentValue = this.currentValue;

			if (typeof currentValue === 'number') {
				//严格模式
				if(this.stepStrictly) {
					console.log('stepStrictly', this.currentValue);
				}
				if (this.precision !== undefined) {
					currentValue = currentValue.toFixed(this.precision);
				}
			}
			
			return currentValue;
		},
		controlsAtRight() {
			return this.controlsPosition === 'right';
		},
		inputNumberSize() {
			return this.size;
		},
		inputNumberDisabled() {
			return this.disabled;
		},
	},
	methods: {
		toPrecision(num, precision) {
			if (precision === undefined) precision = this.numPrecision;
			return parseFloat(Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision));
		},
		handleInputChange (value) {
			const newVal = value === '' ? undefined : Number(value);

			if (!isNaN(newVal) || value === '') {
				this.setCurrentValue(newVal);
			}
			this.userInput = null;//用于输入相同值时再次触发该回调
		},
		_increase (value, step) {
			return parseFloat(value) + step;
		},
		increase () {
			if (this.inputNumberDisabled || this.maxDisabled) return;
			const value = this.value || 0;
			const newVal = this._increase(value, this.step);
			this.setCurrentValue(newVal);
		},
		_decrease (value, step) {
			return parseFloat(value) - step;
		},
		decrease () {
			if (this.inputNumberDisabled || this.minDisabled) return;
			const value = this.value || 0;
			const newVal = this._decrease(value, this.step);
			this.setCurrentValue(newVal);
		},
		handleBlur(event) {
			this.$emit('blur', event);
		},
		handleFocus(event) {
			this.$emit('focus', event);
		},
		handleInput (value) {
			this.userInput = value;
		},
		setCurrentValue (newVal) {
			const oldVal = this.currentValue;
			if (typeof newVal === 'number' && this.precision !== undefined) {
				newVal = this.toPrecision(newVal, this.precision);
			}
			if (newVal >= this.max) newVal = this.max;
			if (newVal <= this.min) newVal = this.min;
			if (oldVal === newVal) return;
			this.userInput = null;
			this.$emit('input', newVal);
			this.$emit('change', newVal, oldVal);
			this.currentValue = newVal;
		},
	},
}
</script>
